home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / x2ftp / msdos / libs / knowhow4 / basica.cpp < prev    next >
C/C++ Source or Header  |  1994-11-03  |  8KB  |  400 lines

  1. #include "slang.h"
  2. #include "nret.h"
  3. //////////////////////////
  4. int Slang::get_argument(double* x)
  5.     {
  6. /*    get_token();   // line argument
  7.     if(token_type != VARIABLE && token_type != NUMBER
  8.     && token_type != COMMAND && token[0] != '-')
  9.     return 1;
  10.     putback();
  11. */
  12.     get_exp(x);
  13.     return 0;
  14.     }
  15. ////////////////////////////////
  16. char* Slang::get_exp(double* result)
  17.     {
  18.     if(error)
  19.         return NULL;
  20.  
  21.     char* str_value;
  22.     get_token();
  23.     if(!*token)
  24.     { serror(2);  return NULL;    }
  25.     str_value = level2(result);
  26.     return str_value;
  27.     }
  28. ////////////////////////
  29. char* Slang::level2(double* result)
  30.     {
  31.     if(error)
  32.         return NULL;
  33.  
  34.     char op; char* str_value;
  35.     double hold;
  36.     str_value = level3(result);
  37.     while((op = *token) == '+' || op == '-')
  38.     {
  39.     get_token();
  40.     str_value = level3(&hold);         // str_value = !!!
  41.     arith(op, result, &hold);
  42.     }
  43.     return str_value;
  44.     }
  45. //////////////////////////
  46. char* Slang::level3(double* result)
  47.     {
  48.     if(error)
  49.     return NULL;
  50.  
  51.     register char op; char* str_value;
  52.     double hold;
  53.     str_value = level4(result);
  54.     while((op = *token) == '*' || op == '/' || op == '%')
  55.     {
  56.     get_token();
  57.     str_value = level4(&hold);   // str_value = !!!
  58.     arith(op, result, &hold);
  59.     }
  60.     return str_value;
  61.     }
  62. //////////////////////////
  63. char* Slang::level4(double* result)
  64.     {
  65.     if(error)
  66.         return NULL;
  67.  
  68.     double hold;  char* str_value;
  69.     str_value = level5(result);
  70.     if(*token == '^')
  71.     {
  72.     get_token();
  73.     str_value = level4(&hold);    // str_value = !!!!
  74.     arith('^', result, &hold);
  75.     }
  76.     return str_value;
  77.     }
  78. //////////////////////////
  79. char* Slang::level5(double* result)
  80.     {
  81.     if(error)
  82.     return NULL;
  83.  
  84.     register char op; char* str_value;
  85.     op = 0;
  86.     if((token_type == DELIMITER) && *token == '+' || *token == '-')
  87.     {
  88.     op = *token;
  89.     get_token();
  90.     }
  91.     str_value = level6(result);
  92.     if(op)
  93.     unary(op, result);
  94.     return str_value;
  95.     }
  96. ////////////////////////////
  97. char* Slang::level6(double* result)
  98.     {
  99.     if(error)
  100.     return NULL;
  101.  
  102.     if((*token == '(') && (token_type == DELIMITER))
  103.     {
  104.     get_token();
  105.     level2(result);
  106.     if(*token != ')')
  107.         { serror(1); return NULL; }
  108.     get_token();
  109.     }
  110. //    else
  111.     {
  112.     return level7(result);
  113.     }
  114.     }
  115.  
  116.  
  117. ///////////////////////////
  118. char* Slang::level7(double* result)
  119.     {
  120.     if(error)
  121.     return NULL;
  122.  
  123.     if(*token == '@')    // write alse possibility of retusn STR
  124.     {
  125.     gosub();
  126.     *result = variables->find("retval")->d;
  127.     get_token();
  128.     variable_type = REAL;
  129.     return NULL;
  130.     }
  131.     else
  132.     {
  133.     if(*prog == '[')
  134.         {
  135. //            putback();
  136.         delete theName;
  137.         theName = strdup(token);
  138.         get_token();              // '['
  139.         get_token();              // index expression
  140.         level2(result);
  141.         if(*token != ']')
  142.         { serror(19); return NULL; }
  143. //        get_token();
  144.         token_type = VARIABLE;
  145.         strcpy(token, theName);
  146.         }
  147.  
  148.     return primitive(result);
  149.     }
  150.     }
  151.  
  152.  
  153. ///////////////////////////
  154. char* Slang::primitive(double * result)
  155.     {
  156.     if(error)
  157.     return NULL;
  158.     switch(token_type)
  159.     {
  160.     case VARIABLE:
  161.         Variable* v;
  162.         v = variables->find(token);
  163.         variable_type = v->type;
  164.         switch(v->type)
  165.         {
  166.         case REAL:
  167.             *result = v->d;
  168.             get_token(); return NULL;
  169.         case ARRAY:
  170.             *result = v->da[(int)(*result)];
  171.             get_token();
  172.             return NULL;
  173.         case STR :
  174.             *result = v->d;
  175.             char* str_value = v->s;
  176.             get_token();
  177.             return str_value;
  178.         }
  179.         return 0;
  180.     case NUMBER:
  181.         char* endptr;
  182.         *result = strtod(token, &endptr);
  183.         get_token();
  184.         variable_type = REAL;
  185.         return NULL;
  186.     case COMMAND:
  187.         math(result); get_token(); return NULL;
  188.     default:
  189. //        serror(0);
  190.         return NULL;
  191.     }
  192.     }
  193. //////////////////////////////
  194. void Slang::arith(char o, double* r, double* h)
  195.     {
  196.     if(error)
  197.     return;
  198.  
  199.     double t, ex;
  200.     switch(o)
  201.     {
  202.     case '-':
  203.         *r = *r - *h;
  204.         break;
  205.     case '+':
  206.         *r = *r + *h;
  207.         break;
  208.     case '*':
  209.         *r = *r * *h;
  210.         break;
  211.     case '/':
  212.         *r = (*r) / (*h);
  213.         break;
  214.     case '%':
  215.         t = (*r) / (*h);
  216.         *r = *r - (t * (*h));
  217.         break;
  218.     case '^':
  219.         ex = *r;
  220.         *r = pow(ex, *h);
  221.         break;
  222.     }
  223.     }
  224. ///////////////////////
  225. void Slang::unary(char o, double* r)
  226.     {
  227.     if(o == '-')
  228.     *r = -(*r);
  229.     }
  230. /////////////////////////////
  231. void Slang::error_report(char* text)  // Overload for your own print
  232.     {
  233.     printf("%s", text);
  234.     }
  235. /////////////////////
  236. void Slang::serror(int err)
  237.     {
  238.     char c = prog[0];                       // Get line number
  239.     prog[0] = '\0';
  240.     char ln[5];
  241.     itoa(nRet(program) + 1, ln, 10);
  242.     prog[0] = c;
  243.  
  244.     int l;                                  // line: 10; file: work.vec
  245.     char s[160];
  246.     char* s1 = s;
  247.     strcpy(s1, "line: ");
  248.     s1 += 6;                                 // strlen("line: ");
  249.     strcpy(s1, ln);
  250.     s1 += strlen(ln);
  251.     strcpy(s1, "\nfile: ");
  252.     s1 += 7;
  253.     strcpy(s1, playstack[play_used]->prog);
  254.     s1 += strlen(playstack[play_used]->prog);
  255.     strcpy(s1, "\n");
  256.     s1++;
  257.     strcpy(s1, error_string[err]);
  258.     error_report(s);
  259.     error = 1;
  260.     }
  261. //////////////////////////
  262. int Slang::get_token()
  263.     {
  264.     if(error)
  265.     return NULL;
  266.  
  267.     char* temp;
  268.     token_type = 0; tok = 0;
  269.     temp = token;
  270.     if(*prog == '\0')
  271.     {
  272.     *token = 0;
  273.     tok = FINISHED;
  274.     return(token_type = DELIMITER);
  275.     }
  276.     while(iswhite(*prog))
  277.     ++prog;
  278.     if(*prog == '/' && *(prog + 1) == '*' && *prog + 1) // Remarked block
  279.         {
  280.         while(1)
  281.         {
  282.         if(*prog == '*' && *(prog + 1) == '/')
  283.                 {
  284.                 tok = REMARK_BLOCK;
  285.                 prog += 2;
  286.                 return token_type = STRING;
  287.                 }
  288.             else if(!(*(prog + 1))) // End of remarked block
  289.                 {
  290.         tok = FINISHED;
  291.                 return token_type = DELIMITER;
  292.                 }
  293.             *prog++;
  294.             }
  295.         }
  296.  
  297.     switch(*prog)
  298.     {
  299.     case '&':
  300.         tok = REMARK;
  301.         find_eol();
  302.         return(token_type = STRING);
  303.     case '@':
  304.         tok = GOSUB;
  305.         *temp++ = *prog++;
  306.         return(token_type = ALPHA);
  307.         case '!':
  308.         tok = LABEL;
  309.         *temp++ = *prog++;
  310.         return(token_type = ALPHA);
  311.     case ':' :
  312.     case '\r':
  313.         char c = prog[0];
  314.         ++prog;
  315.         if((*prog != '\0') && (c != ':'))
  316.         ++prog;
  317.         tok = EOL; *token = '\r';
  318.         token[1] = '\n'; token[2] = 0;
  319.         return(token_type = DELIMITER);
  320.     case '"':
  321.         prog++;
  322.         while(*prog != '"' && *prog != '\r')
  323.         *temp++ = *prog++;
  324.         if(*prog == '\r')
  325.         { serror(14); return 0; }
  326.         prog++; *temp = 0;
  327.         return(token_type = QUOTE);
  328.     }
  329.     if(strchr("<>=", *prog) && strchr("<>=", *(prog + 1)))
  330.     {
  331.     *temp++ = *prog++;
  332.     *temp++ = *prog++;
  333.     *temp = 0;
  334.     return(token_type = DELIMITER);
  335.     }
  336.     if(strchr(" +-^/*%=;(),<>[]", *prog))
  337.     {
  338.     *temp = *prog;
  339.     prog++;
  340.     temp++;
  341.     *temp = 0;
  342.     return(token_type = DELIMITER);
  343.     }
  344.  
  345.     if(isdigit(*prog))
  346.     {
  347.     while(!isdelim(*prog))
  348.         *temp++ = *prog++;
  349.     *temp = '\0';
  350.     return(token_type = NUMBER);
  351.     }
  352.     if(isalpha(*prog))
  353.     {
  354.     while(!isdelim(*prog))
  355.         *temp++ = *prog++;
  356.     token_type = STRING;
  357.     }
  358.     *temp = '\0';
  359.     if(token_type == STRING)
  360.     {
  361.     int i;    char* p;
  362.     p = token;
  363.     while(*p)
  364.         {       *p = tolower(*p);        p++;    }
  365.     tok = 0;
  366.     for(i = 0; *TABLE[i].command; i++)
  367.         if(!strcmp(TABLE[i].command, token))
  368.         { tok = (int)TABLE[i].tok;  break;  }
  369.  
  370.     if(!tok)
  371.         token_type = VARIABLE;
  372.     else
  373.         token_type = COMMAND;
  374.     }
  375.     return token_type;
  376.     }
  377. ////////////////////////////
  378. void Slang::putback()
  379.     {
  380.     char* t;
  381.     t = token;
  382.     for(; *t; t++)
  383.     prog--;
  384.     }
  385. //////////////////////////
  386. int Slang::isdelim(char c)
  387.     {
  388.     if(strchr(" ;,+-<>/*%^=():[]", c) || c == 9 || c == '\r' || c == 0)
  389.     return 1;
  390.     return 0;
  391.     }
  392. /////////////////////////
  393. int Slang::iswhite(char c)
  394.     {
  395.     if(c == ' ' || c == '\t')
  396.     return 1;
  397.     else return 0;
  398.     }
  399.  
  400.